const MongoClient = require('mongodb').MongoClient;
const config = require('config');

/**
 * DatabaseManager类 - 数据库连接管理器
 * 使用连接池管理MongoDB连接，提高性能
 */
class DatabaseManager {
    constructor(mongoUrl,mongoDb) {
        this.mongoUrl = mongoUrl;// process.env.mongo_url || config.mongo.url;
        this.mongoDb = mongoDb;// process.env.mongo_db || config.mongo.db;
        this.client = null;
        this.db = null;
        this.isConnected = false;
        this.connectionPromise = null;
        this.maxPoolSize = process.env.mongo_max_pool_size || config.mongo.maxPoolSize || 10;
        this.minPoolSize = process.env.mongo_min_pool_size || config.mongo.minPoolSize || 5;
        this.maxIdleTimeMS = process.env.mongo_max_idle_time_ms || config.mongo.maxIdleTimeMS || 30000;
        this.connectTimeoutMS = process.env.mongo_connect_timeout_ms || config.mongo.connectTimeoutMS || 10000;
        this.socketTimeoutMS = process.env.mongo_socket_timeout_ms || config.mongo.socketTimeoutMS || 45000;
    }

    /**
     * 获取数据库连接选项
     * @returns {object} - 连接选项
     */
    getConnectionOptions() {
        return {
            maxPoolSize: this.maxPoolSize,
            minPoolSize: this.minPoolSize,
            maxIdleTimeMS: this.maxIdleTimeMS,
            connectTimeoutMS: this.connectTimeoutMS,
            socketTimeoutMS: this.socketTimeoutMS,
            serverSelectionTimeoutMS: 5000,
            retryWrites: true,
            w: 'majority'
        };
    }

    /**
     * 连接到数据库
     * @returns {Promise<object>} - 数据库连接对象 {client, db}
     */
    async connect() {
        if (this.isConnected && this.client && this.db) {
            return { client: this.client, db: this.db };
        }

        // 如果正在连接中，等待连接完成
        if (this.connectionPromise) {
            return this.connectionPromise;
        }

        this.connectionPromise = this._performConnection();
        return this.connectionPromise;
    }

    /**
     * 执行实际的连接操作
     * @returns {Promise<object>} - 数据库连接对象
     */
    async _performConnection() {
        try {
            console.log('正在连接到MongoDB...');
            
            const options = this.getConnectionOptions();
            this.client = await MongoClient.connect(this.mongoUrl, options);
            this.db = this.client.db(this.mongoDb);
            this.isConnected = true;

            console.log(`MongoDB连接成功 - 数据库: ${this.mongoDb}`);
            console.log(`连接池配置 - 最大连接数: ${this.maxPoolSize}, 最小连接数: ${this.minPoolSize}`);

            // 监听连接事件
            this.client.on('close', () => {
                console.log('MongoDB连接已关闭');
                this.isConnected = false;
                this.client = null;
                this.db = null;
            });

            this.client.on('error', (error) => {
                console.error('MongoDB连接错误:', error);
                this.isConnected = false;
            });

            return { client: this.client, db: this.db };
        } catch (error) {
            console.error('MongoDB连接失败:', error);
            this.isConnected = false;
            this.client = null;
            this.db = null;
            throw error;
        } finally {
            this.connectionPromise = null;
        }
    }

    /**
     * 获取数据库实例
     * @returns {Promise<object>} - 数据库实例
     */
    async getDb() {
        const { db } = await this.connect();
        return db;
    }

    /**
     * 获取客户端实例
     * @returns {Promise<object>} - 客户端实例
     */
    async getClient() {
        const { client } = await this.connect();
        return client;
    }

    /**
     * 获取集合
     * @param {string} collectionName - 集合名称
     * @returns {Promise<object>} - 集合实例
     */
    async getCollection(collectionName) {
        const db = await this.getDb();
        return db.collection(collectionName);
    }

    /**
     * 检查连接状态
     * @returns {boolean} - 是否已连接
     */
    isConnectionActive() {
        return this.isConnected && this.client && this.db;
    }

    /**
     * 获取连接池状态
     * @returns {Promise<object>} - 连接池状态信息
     */
    async getPoolStatus() {
        if (!this.client) {
            return { connected: false, poolSize: 0 };
        }

        try {
            const adminDb = this.client.db('admin');
            const result = await adminDb.command({ serverStatus: 1 });
            
            return {
                connected: this.isConnected,
                poolSize: result.connections?.current || 0,
                available: result.connections?.available || 0,
                active: result.connections?.active || 0
            };
        } catch (error) {
            console.error('获取连接池状态失败:', error);
            return { connected: this.isConnected, error: error.message };
        }
    }

    /**
     * 健康检查
     * @returns {Promise<object>} - 健康状态
     */
    async healthCheck() {
        try {
            const db = await this.getDb();
            await db.command({ ping: 1 });
            
            const poolStatus = await this.getPoolStatus();
            
            return {
                status: 'healthy',
                timestamp: new Date().toISOString(),
                poolStatus
            };
        } catch (error) {
            return {
                status: 'unhealthy',
                timestamp: new Date().toISOString(),
                error: error.message
            };
        }
    }

    /**
     * 关闭数据库连接
     * @returns {Promise<void>}
     */
    async close() {
        if (this.client) {
            try {
                await this.client.close();
                console.log('MongoDB连接已关闭');
            } catch (error) {
                console.error('关闭MongoDB连接时发生错误:', error);
            } finally {
                this.isConnected = false;
                this.client = null;
                this.db = null;
            }
        }
    }

    /**
     * 优雅关闭
     * @returns {Promise<void>}
     */
    async gracefulShutdown() {
        console.log('正在优雅关闭数据库连接...');
        await this.close();
    }
}

module.exports = DatabaseManager; 